//
//  ViewController.m
//  RSADemo


#import "rsaViewController.h"
#import "DDRSAWrapper.h"
#import "DDRSAWrapper+openssl.h"
@interface rsaViewController (){
    
    RSA *publicKey;
    RSA *privateKey;
    
    SecKeyRef publicKeyRef;
    SecKeyRef privateKeyRef;
    
    NSString *_publicKeyBase64;
    NSString *_privateKeyBase64;
    
    NSString *_cipherString;
    DDRSAWrapper *_wrapper;
    
}
@property (weak, nonatomic) IBOutlet UITextView *logTextView;

@property (weak, nonatomic) IBOutlet UITextField *mingWenTextFiled;

@end

@implementation rsaViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    _wrapper = [[DDRSAWrapper alloc] init];
    
}
- (IBAction)resetAll:(id)sender {
    
    publicKey = nil;
    privateKey = nil;
    
    publicKeyRef = nil;
    privateKeyRef = nil;
    
    _publicKeyBase64 = nil;
    _privateKeyBase64 = nil;
    
    _cipherString = nil;
    self.logTextView.text = nil;
    
    
    
}
#pragma mark - openssl
#pragma mark ---生成密钥对
- (IBAction)opensslGenerate{
    if ([DDRSAWrapper generateRSAKeyPairWithKeySize:2048 publicKey:&publicKey privateKey:&privateKey]) {
        
        char * m = [DDRSAWrapper openssl_modFromPublicKey:publicKey];
        char * e = [DDRSAWrapper openssl_expFromPublicKey:publicKey];;
        
        _publicKeyBase64 = [DDRSAWrapper base64EncodedStringPublicKey:publicKey];
        _privateKeyBase64 = [DDRSAWrapper base64EncodedStringPrivateKey:privateKey];
        NSLog(@"%@",_publicKeyBase64);
        NSLog(@"%@",_privateKeyBase64);
        
        NSString *logText = [NSString stringWithFormat:@"openssl 生成密钥成功！\n公钥-----\n模数：%s\n指数：%s\n-------",m,e];
        [self addlogText:logText];
    }
}
#pragma mark ---读取密钥对
- (IBAction)opensslReadPublicKeyPEM {
    if(!_publicKeyBase64) {
        NSString *logText = [NSString stringWithFormat:@"%@\n 无PEM信息\n",self.logTextView.text];
        self.logTextView.text = logText;
        return;
    }
    publicKey = [DDRSAWrapper openssl_publicKeyFromBase64:_publicKeyBase64];
    
    if (publicKey ) {
        [self addlogText:@"openssl 读出公钥pem成功"];
    }
}

- (IBAction)opensslReadPrivateeyPEM {
    if(!_privateKeyBase64) {
        [self addlogText:@"无PEM信息"];
        return;
    }
    privateKey = [DDRSAWrapper openssl_privateKeyFromBase64:_privateKeyBase64];
    if (privateKey ) {
        
        [self addlogText:@"openssl 读出私钥pem成功"];
    }
}


#pragma mark ---公钥加密 && 私钥解密
- (IBAction)opensslPubcliKeyEncrypt {
    if(!publicKey) {
        [self addlogText:@"无RSA公钥"];
        return;
    }
    if (!self.mingWenTextFiled.text) {
        [self addlogText:@"无明文数据"];
        return;
    }
    
    NSData *plainData = [self.mingWenTextFiled.text dataUsingEncoding:NSUTF8StringEncoding];
    
    NSData *cipherData = [DDRSAWrapper openssl_encryptWithPublicKey:publicKey
                                                          plainData:plainData
                                                            padding:RSA_PKCS1_PADDING];
    
    _cipherString = [cipherData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    NSString *logText = [NSString stringWithFormat:@"openssl 公钥加密：\n%@",_cipherString];
    [self addlogText:logText];
    
    
}

- (IBAction)opensslPrivateKeyDecrypt {
    if(!privateKey) {
        [self addlogText:@"无RSA私钥"];
        return;
    }
    if (!_cipherString) {
        [self addlogText:@"无密文数据"];
        return;
    }
    
    NSData *cipherData = [[NSData alloc] initWithBase64EncodedString:_cipherString options:NSDataBase64DecodingIgnoreUnknownCharacters];
    
    NSData *plainData = [DDRSAWrapper openssl_decryptWithPrivateKey:privateKey
                                                         cipherData:cipherData
                                                            padding:RSA_PKCS1_PADDING];
    
    NSString *outputPlainString = [[NSString alloc] initWithData:plainData encoding:NSUTF8StringEncoding];
    
    if ([outputPlainString isEqualToString:self.mingWenTextFiled.text]) {
        NSString *logText = [NSString stringWithFormat:@"openssl 私钥解密：\n%@",outputPlainString];
        [self addlogText:logText];
    } else {
        NSString *logText = [NSString stringWithFormat:@"openssl 私钥解密失败"];
        [self addlogText:logText];
    }
}

#pragma mark ---私钥加密 && 公钥解密
- (IBAction)opensslPrivateEncrypt:(id)sender {
    if(!privateKey) {
        [self addlogText:@"无RSA私钥"];
        return;
    }
    
    if (!self.mingWenTextFiled.text) {
        [self addlogText:@"无明文数据"];
        return;
    }
    NSData *plainData = [self.mingWenTextFiled.text dataUsingEncoding:NSUTF8StringEncoding];
    
    NSData *cipherData = [DDRSAWrapper openssl_encryptWithPrivateRSA:privateKey
                                                           plainData:plainData
                                                             padding:RSA_PKCS1_PADDING];
    
    _cipherString = [cipherData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    NSString *logText = [NSString stringWithFormat:@"openssl 私钥加密：\n%@",_cipherString];
    [self addlogText:logText];
    
}
- (IBAction)opensslPublicKeyDecrypt:(id)sender {
    
    if(!publicKey) {
        [self addlogText:@"无RSA公钥"];
        return;
    }
    
    if (!_cipherString) {
        [self addlogText:@"无密文数据"];
        return;
    }
    
    NSData *cipherData = [[NSData alloc] initWithBase64EncodedString:_cipherString options:NSDataBase64DecodingIgnoreUnknownCharacters];
    
    NSData *plainData = [DDRSAWrapper openssl_decryptWithPublicKey:publicKey
                                                        cipherData:cipherData
                                                           padding:RSA_PKCS1_PADDING];
    
    NSString *outputPlainString = [[NSString alloc] initWithData:plainData encoding:NSUTF8StringEncoding];
    if ([outputPlainString isEqualToString:self.mingWenTextFiled.text]) {
        NSString *logText = [NSString stringWithFormat:@"openssl 公钥解密成功：\n%@",outputPlainString];
        [self addlogText:logText];
    } else {
        NSString *logText = [NSString stringWithFormat:@"openssl 公钥解密失败"];
        [self addlogText:logText];
    }
    
}
#pragma mark - help method
- (void)addlogText:(NSString *)text {
    NSString *logText = [NSString stringWithFormat:@"%@\n%@\n",self.logTextView.text,text];
    self.logTextView.text = logText;
    [self scrollsToBottomAnimated:YES];
}

- (void)scrollsToBottomAnimated:(BOOL)animated {
    
    [_logTextView scrollRangeToVisible:NSMakeRange(_logTextView.text.length, 1)];
}

- (NSString *)stringFromData:(NSData *)data {
    return  [[[[data description] stringByReplacingOccurrencesOfString: @"<" withString: @""]
              stringByReplacingOccurrencesOfString: @">" withString: @""]
             stringByReplacingOccurrencesOfString: @" " withString: @""];
}

- (NSData *)convertHexStrToData:(NSString *)str {
    if (!str || [str length] == 0) {
        return nil;
    }
    
    NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
    NSRange range;
    if ([str length] % 2 == 0) {
        range = NSMakeRange(0, 2);
    } else {
        range = NSMakeRange(0, 1);
    }
    for (NSInteger i = range.location; i < [str length]; i += 2) {
        unsigned int anInt;
        NSString *hexCharStr = [str substringWithRange:range];
        NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
        
        [scanner scanHexInt:&anInt];
        NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
        [hexData appendData:entity];
        
        range.location += range.length;
        range.length = 2;
    }
    return hexData;
}

@end

